<?php
/**
 * 合同仓库
 * @author wangwx 2015-5-12
 */
namespace common\repositories\common;

use common\repositories\BaseRepository;
use common\entities\common\MyscrmApplicationEntity;
use common\entities\common\MyscrmContractEntity;
use common\entities\common\MyscrmFunctionupgradeEntity;
use common\entities\common\MyscrmOrganizationToAuthorizeEntity;
use common\entities\common\MyscrmOrganizationToPackageEntity;
use common\entities\common\MyscrmPackageEntity;
use common\entities\common\MyscrmPackageToApplicationEntity;
use common\support\StringHelper;
use yii\helpers\ArrayHelper;
use Yii;

class MyscrmContractRepository extends BaseRepository {
	
	/**
	 * 根据合同编号，获取模型数据
	 * @param string $contractNum 合同编号
	 * @param string $orgId 租户ID
	 * @return MyscrmContractEntity array 实体数据
	 */
	public function getContractByContractNum($contractNum, $orgId=null) {
        $contract_entity = new MyscrmContractEntity();
		return $contract_entity->getContractByContractNum($contractNum, $orgId);
	}

	/**
	 * 根据租户ID，获取模型数据
	 * @param $organizationId
	 * @return array|MyscrmContractEntity[]
	 */
	public function getContractByOrganizationId($organizationId){
		return MyscrmContractEntity::findAll([
			'OrganizationId' => $organizationId
		]);
	}


	/**
	 * 保存合同
	 * @param $contractInfo
	 * @return array
	 * @throws \Exception
	 */
	public function saveContract($contractInfo){

		//查询是更新还是插入
		if(isset($contractInfo['contract_id']) && !empty($contractInfo['contract_id'])){ //如果传递了contract_id，则表示一定为编辑模式，则验证是否存在
			$contractEntity = $this->getContractById(ArrayHelper::getValue($contractInfo, 'contract_id'));
			if(empty($contractEntity) || $contractEntity['Status'] != 1){
				throw $this->throwException("不存在的合同或合同已作废");
			}
		}else{
			$contractEntity = $this->getContractByContractNum(ArrayHelper::getValue($contractInfo, 'contract_num'),
				ArrayHelper::getValue($contractInfo, 'organization_id'));
			if(!empty($contractEntity) && $contractEntity['Status'] != 1){
				throw $this->throwException("合同已作废不允许编辑");
			}
		}

		$contractArr = [];
		$isInsert = true;
		if(empty($contractEntity)){
			$contractArr['ContractId'] = StringHelper::uuid();
		}else{
			$contractArr['ContractId'] = $contractEntity['ContractId'];
			$isInsert = false;
		}
		$contractId = $contractArr['ContractId'];
		$contractArr['ContractNum'] = ArrayHelper::getValue($contractInfo, 'contract_num');
		$contractArr['OrganizationId'] = ArrayHelper::getValue($contractInfo, 'organization_id');
		$contractArr['PartyA'] = ArrayHelper::getValue($contractInfo, 'party_a');
		$contractArr['ContractType'] = ArrayHelper::getValue($contractInfo, 'contract_type');
		$contractArr['BeginOn'] = ArrayHelper::getValue($contractInfo, 'begin_on');
		$contractArr['EndOn'] = ArrayHelper::getValue($contractInfo, 'end_on');
		$contractArr['Status'] = ArrayHelper::getValue($contractInfo, 'status', 1); //1为激活，2为废弃

		$connection = MyscrmContractEntity::getDb();

        if($isInsert){
            $rs = $connection->createCommand()
                ->insert(MyscrmContractEntity::tableName(), $contractArr)
                ->execute();
        }else{
            unset($contractArr['ContractId']);
            $rs = $connection->createCommand()
                ->update(MyscrmContractEntity::tableName(), $contractArr, "ContractId='{$contractId}'")
                ->execute();
        }

		return $contractId;
	}

    public function getContractById($contractId){
        return MyscrmContractEntity::findOne([
            "ContractId" => $contractId
        ]);
    }

	public function updateStatus($orgId, $contractId, $status){
        $contract = MyscrmContractEntity::findOne([
			"ContractId" => $contractId,
			"OrganizationId" => $orgId
		]);
		$contract['Status'] = $status;
		return $contract->save();
	}

	/**
	 * 获取合同的总授权数
	 * @param $orgId
	 * @param $contractId
	 * @return int
	 */
	public function getContractTotalNum($orgId, $contractId){
        $otoas = MyscrmOrganizationToAuthorizeEntity::findAll([
			'OrganizationId' => $orgId,
			'ContractId' => $contractId
		]);
		$totalNum = 0;
		if(!empty($otoas)){

			foreach($otoas as $otoa){
				$totalNum += intval($otoa['TotalNum']);
			}
		}
		return $totalNum;
	}

	/**
	 * 根据租户ID和合同ID获取合同详情
	 * @param $orgId
	 * @param $contractId
	 * @return array
	 * @throws \Exception
	 */
	public function getContractDetailById($orgId, $contractId){
		$contract = $this->getContractById($contractId);
		if(empty($contract)){
			throw $this->throwException("不存在的合同");
		}

		if($contract['Status'] != 1){
			throw $this->throwException("作废合同不允许编辑");
		}
		$pkgs = MyscrmPackageEntity::find()->all();
		$usedNums = MyscrmAuthorizeRepository::getUsedAuthorizeNum($orgId, true);
		$isAdv = MyscrmFunctionupgradeEntity::isAdvancedVersionYdxs($orgId);
		$resResult = [];
        foreach($pkgs as $pkg){
			// 查询商户是否存在该pkg
			$pkgInfo = $pkg->toArray();
			$pkgInfo['total_num'] = 0;
			$pkgInfo['used_num'] = 0;
			$orgPkg = MyscrmOrganizationToPackageEntity::findOne([
				"organization_id" => $orgId,
				"package_id" => $pkg['id'],
				'contract_id' => $contractId
			]);
			if(!empty($orgPkg)){
				$pkgToApps = MyscrmPackageToApplicationEntity::findAll([
					'package_id' =>  $pkg['id'],
				]);

				if(!empty($pkgToApps)){
					foreach($pkgToApps as $pkgToApp){
						$auths = MyscrmOrganizationToAuthorizeEntity::findAll([
							'ApplicationId' => $pkgToApp['application_id'],
							'OrganizationId' => $orgId,
							'ContractId' => $contractId
						]);
						$pkgInfoTotalNum = 0;
						$pkgInfoUsedNum = 0;
						if(!empty($auths)){
							foreach($auths as $auth){
								$pkgInfoTotalNum += intval($auth['TotalNum']);
								if(isset($usedNums[$auth['Id']])){
									$pkgInfoUsedNum += intval($usedNums[$auth['Id']]);
								}
							}
						}

						if($pkgInfoTotalNum > $pkgInfo['total_num']){
							$pkgInfo['total_num'] = $pkgInfoTotalNum;
						}
						if($pkgInfoUsedNum > $pkgInfo['used_num']){
							$pkgInfo['used_num'] = $pkgInfoUsedNum;
						}
					}

				}
			}
			// 如果租户没有购买移动销售高级版，则移动销售包的授权数和已用授权数置为0
			if($pkgInfo['unique_name'] == MyscrmPackageEntity::YDXS && !$isAdv){
				$pkgInfo['total_num'] = 0;
				$pkgInfo['used_num'] = 0;
			}
			$resResult []= $pkgInfo;
		}
		$contract = $contract->toArray();
		$contract["packages"] = $resResult;
		return $contract;
	}

	/**
	 * 根据套餐包ID获取其详情及合同列表
	 * @param $orgId
	 * @param $pkgId
	 * @param bool $useCurl
	 * @return array
	 * @throws \Exception
	 */
	public function getAuthorizedPackageById($orgId, $pkgId, $useCurl=false){
		$pkg = MyscrmPackageEntity::findOne([
			'id' => $pkgId
		]);

		if(empty($pkg)){
			throw $this->throwException('不存在的套餐包'); 
		}

		$pkgInfo = $pkg->toArray();
		$orgPkgs = MyscrmOrganizationToPackageEntity::findAll([
			'organization_id' => $orgId,
			'package_id' => $pkgId,
		]);
		$pkgInfo['contracts'] = [];
		$pkgInfo['total_num'] = 0;
		if($useCurl){
			$usedNums = MyscrmAuthorizeRepository::getUsedAuthorizeNum($orgId, true);
			$pkgInfo['used_num'] = 0;
		}

		// 拿授权
		$pkgToApps = MyscrmPackageToApplicationEntity::findAll([ // 一个包有哪些应用
			"package_id" => $pkgId
		]);
		if(!empty($orgPkgs) && !empty($pkgToApps)){
			foreach($orgPkgs as $orgPkg){
				// 获取合同
				$now = date("Y-m-d H:i:s");
				$contracts = MyscrmContractEntity::find()->where([
					'OrganizationId' => $orgId, 'ContractId' => $orgPkg['contract_id'], 'Status' => 1
				])->andWhere(['>', 'EndOn', $now])->all();
				if(!empty($contracts)){
					foreach($contracts as $contract){
						$pkgInfo['contracts'][$contract['ContractId']] = $contract->toArray();
						$pkgInfo['contracts'][$contract['ContractId']]['total_num'] = 0;
						if($useCurl){
							$pkgInfo['contracts'][$contract['ContractId']]['used_num'] = 0;
						}
						foreach($pkgToApps as $pkgToApp) { // 遍历包中的应用
							$orgAuths = MyscrmOrganizationToAuthorizeEntity::findAll([ //找到授权
								"ApplicationId" => $pkgToApp['application_id'],
								"OrganizationId" => $orgId,
								"ContractId" => $contract['ContractId']
							]);
							if(!empty($orgAuths)){
                                 foreach($orgAuths as $orgAuth){
									 if($orgAuth['TotalNum'] > $pkgInfo['contracts'][$contract['ContractId']]['total_num']){
										 $pkgInfo['contracts'][$contract['ContractId']]['total_num'] = $orgAuth['TotalNum'];
									 }
									 if($useCurl){
										 $orgUsedNum = intval(ArrayHelper::getValue($usedNums, $orgAuth['Id']));
										 if($orgUsedNum > $pkgInfo['contracts'][$contract['ContractId']]['used_num']){
											 $pkgInfo['contracts'][$contract['ContractId']]['used_num'] = $orgUsedNum;
										 }

									 }
								 }
							}
						}
                        if($pkgInfo['contracts'][$contract['ContractId']]['total_num'] > 0){
							$pkgInfo['total_num'] += $pkgInfo['contracts'][$contract['ContractId']]['total_num'];
							if($useCurl){
								$pkgInfo['used_num'] += $pkgInfo['contracts'][$contract['ContractId']]['used_num'];
							}
						}else{
							unset($pkgInfo['contracts'][$contract['ContractId']]);
						}

					}
				}

			}
		}
		$pkgInfo['contracts'] = array_values($pkgInfo['contracts']);
		return $pkgInfo;

	}


	/**
	 * 获取租户所有的包及其合同
	 * @param $orgId
	 * @param bool $useCurl
	 * @return array
	 * @throws \Exception
	 */
	public function getAuthorizedPackagesAndContractsByOrgId($orgId, $useCurl=false){
		$orgPkgs = MyscrmOrganizationToPackageEntity::findAll([
			"organization_id" => $orgId
		]);

		$pkgRes = [];
		$pkgToAppsRes = [];
		$appRes = [];
		$isAdv = MyscrmFunctionupgradeEntity::isAdvancedVersionYdxs($orgId);
		if(!empty($orgPkgs)){
			if($useCurl){
				$usedNums = MyscrmAuthorizeRepository::getUsedAuthorizeNum($orgId, true);
			}
			foreach($orgPkgs as $orgPkg){
				if(!isset($pkgRes[$orgPkg['package_id']])){
					$pkg = MyscrmPackageEntity::findOne([
						"id" => $orgPkg['package_id']
					]);
					if(!empty($pkg)){
						$pkgRes[$orgPkg['package_id']] = $pkg->toArray();
						$pkgRes[$orgPkg['package_id']]['total_num'] = 0;
						$pkgRes[$orgPkg['package_id']]['contracts'] = [];
						if($useCurl){
							$pkgRes[$orgPkg['package_id']]['used_num'] = 0;
						}
					}else{
						continue;
					}

					$pkgToApps = MyscrmPackageToApplicationEntity::findAll([ // 一个包有哪些应用
						"package_id" => $orgPkg['package_id']
					]);

					if(!empty($pkgToApps)){
						$pkgToAppsRes[$orgPkg['package_id']] = $pkgToApps;
						$pkgRes[$orgPkg['package_id']]['applications'] = [];

						foreach($pkgToApps as $pkgToApp){
							$app = MyscrmApplicationEntity::findOne([
								'ApplicationId' => $pkgToApp['application_id']
							]);
							if($app){
								$pkgRes[$orgPkg['package_id']]['applications'] []= $app['UniqueName'];
								$appRes[$pkgToApp['application_id']] = $app['UniqueName'];
							}

						}

					}else{
						continue;
					}

				}

				if(isset($pkgToAppsRes[$orgPkg['package_id']])){
					$pkgInfo = $pkgRes[$orgPkg['package_id']];
					// 获取合同
					$now = date("Y-m-d H:i:s");
					$contracts = MyscrmContractEntity::find()->where([
						'OrganizationId' => $orgId, 'ContractId' => $orgPkg['contract_id'], 'Status' => 1
					])->andWhere(['>', 'EndOn', $now])->all();
					if(!empty($contracts)){
						foreach($contracts as $contract){
							$pkgInfo['contracts'][$contract['ContractId']] = $contract->toArray();
							$pkgInfo['contracts'][$contract['ContractId']]['apps'] = [];
							$pkgInfo['contracts'][$contract['ContractId']]['total_num'] = 0;
							if($useCurl){
								$pkgInfo['contracts'][$contract['ContractId']]['used_num'] = 0;
							}
							foreach($pkgToAppsRes[$orgPkg['package_id']] as $pkgToApp) { // 遍历包中的应用
								if(isset($appRes[$pkgToApp['application_id']])){
									//如果是高级版本移动销售而包又是zsslc，那么不将app内容加入zsslc
									if($isAdv && $pkgInfo['unique_name'] == MyscrmPackageEntity::ZSSLC && $appRes[$pkgToApp['application_id']] ==
										MyscrmApplicationEntity::YDXS){
										continue;
									}
                                    //如果不是高级版本移动销售而包又是ydxs，那么不将app内容加入ydxs
									if(!$isAdv && $pkgInfo['unique_name'] == MyscrmPackageEntity::YDXS && $appRes[$pkgToApp['application_id']] ==
										MyscrmApplicationEntity::YDXS){
										continue;
									}
								}

								$orgAuths = MyscrmOrganizationToAuthorizeEntity::findAll([ //找到授权
									"ApplicationId" => $pkgToApp['application_id'],
									"OrganizationId" => $orgId,
									"ContractId" => $contract['ContractId']
								]);
								if(!empty($orgAuths)){
									foreach($orgAuths as $orgAuth){
										if($orgAuth['TotalNum'] > $pkgInfo['contracts'][$contract['ContractId']]['total_num']){
											$pkgInfo['contracts'][$contract['ContractId']]['total_num'] = $orgAuth['TotalNum'];
										}

										if($useCurl){
											$orgUsedNum = intval(ArrayHelper::getValue($usedNums, $orgAuth['Id']));
											if($orgUsedNum > $pkgInfo['contracts'][$contract['ContractId']]['used_num']){
												$pkgInfo['contracts'][$contract['ContractId']]['used_num'] = $orgUsedNum;
											}

										}
										if(isset($appRes[$pkgToApp['application_id']])){
											$pkgInfo['contracts'][$contract['ContractId']]['apps'][$appRes[$pkgToApp['application_id']]] = $orgAuth['Id'];
										}
									}
								}
							}
							if($pkgInfo['contracts'][$contract['ContractId']]['total_num'] > 0){
								$pkgInfo['total_num'] += $pkgInfo['contracts'][$contract['ContractId']]['total_num'];
								if($useCurl){
									$pkgInfo['used_num'] += $pkgInfo['contracts'][$contract['ContractId']]['used_num'];
								}
							}else{
								unset($pkgInfo['contracts'][$contract['ContractId']]);
							}

						}
					}
					$pkgInfo['applications'] = array_unique($pkgInfo['applications']);
					$newApps = [];
					foreach($pkgInfo['applications'] as $appcode){
						//如果是高级版本移动销售而包又是zsslc，那么不将app内容加入zsslc
						if($isAdv && $pkgInfo['unique_name'] == MyscrmPackageEntity::ZSSLC && $appcode == MyscrmApplicationEntity::YDXS){
							continue;
						}
						//如果不是高级版本移动销售而包又是ydxs，那么不将app内容加入ydxs
						if(!$isAdv && $pkgInfo['unique_name'] == MyscrmPackageEntity::YDXS && $appcode == MyscrmApplicationEntity::YDXS){
							continue;
						}
						$newApps []= $appcode;
					}

					$pkgInfo['applications'] = $newApps;

					$pkgRes[$orgPkg['package_id']] = $pkgInfo;
				}

			}
		}
		foreach($pkgRes as $pkgName => $pkgInfo){
			$pkgInfo['contracts'] = array_values($pkgInfo['contracts']);
			$pkgRes[$pkgName] = $pkgInfo;
		}
		return array_values($pkgRes);
	}

}

